package psmanager.swing.model;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;

import psmanager.db.DBManager;
import psmanager.db.types.Cuvar;
import psmanager.db.types.Doktor;
import psmanager.db.types.Osoba;
import psmanager.db.types.Zatvorenik;

public class OsobaModel extends AbstractTableModel {
	private static final long serialVersionUID = -6351154890030430750L;
	
	
	private List<Osoba> osobe;
	private final DBManager dbm;
	

	public OsobaModel(List<Osoba> osobe, final DBManager dbm) {
		this.dbm = dbm;
		this.osobe = new ArrayList<Osoba>(osobe);
	}
	
	@Override
	public Class<?> getColumnClass(int columnIndex) {
		switch(columnIndex) {
		case 0: return String.class;
		case 1: return String.class;
		case 2: return String.class;
		case 3: return String.class;
		case 4: return String.class;
		case 5: return Integer.class;
		default: return String.class;
		}
	}


	@Override
	public String getColumnName(int columnIndex) {
		switch(columnIndex) {
		case 0: return "JMBG";
		case 1: return "Tip";
		case 2: return "Ime";
		case 3: return "Prezime";
		case 4: return "Adresa";
		case 5: return "Dob";
		default: return "";
		}
	}

	@Override
	public int getColumnCount() {
		return 6;
	}
	
	@Override
	public int getRowCount() {
		return osobe.size();
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		switch(columnIndex) {
		case 0: return osobe.get(rowIndex).getJmbg();
		case 1: 
			Osoba osoba = osobe.get(rowIndex);
			if(osoba instanceof Zatvorenik) return "Zatvorenik";
			else if(osoba instanceof Cuvar) return "Čuvar";
			else if(osoba instanceof Doktor) return "Doktor";
			else return "???";
		case 2: return osobe.get(rowIndex).getIme();
		case 3: return osobe.get(rowIndex).getPrezime();
		case 4: return osobe.get(rowIndex).getPrebivaliste();
		case 5: return calcAgeByBirthDate(osobe.get(rowIndex).getRodjen());
		default: return "";
		}
	}

	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		switch(columnIndex) {
		case 0: return false;
		case 1: return false;
		case 5: return false;
		default: return true;
		}
	}
	
	@Override
	public void addTableModelListener(TableModelListener l) {
		// TODO Auto-generated method stub
	}

	@Override
	public void removeTableModelListener(TableModelListener l) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		
		Osoba osobaProto = new Osoba(osobe.get(rowIndex).getJmbg());
		Osoba osobaFromDB = dbm.grabPersonsByQBE(osobaProto).get(0);
		
		switch(columnIndex) {
		case 2: 
			// Osoba u modelu se mijenja jer ima istu referencu...
			osobaFromDB.setIme(aValue.toString());
			dbm.store(osobaFromDB);
			break;
		case 3:
			// Osoba u modelu se mijenja jer ima istu referencu...
			osobaFromDB.setPrezime(aValue.toString());
			dbm.store(osobaFromDB);
			break;
		case 4: 
		}
	}
	
	private int calcAgeByBirthDate(Date birthDate) {
		Calendar current = new GregorianCalendar();
		Calendar cal = Calendar.getInstance();
		if(birthDate == null) return -1;
		cal.setTime(birthDate);
		cal.setTimeInMillis(current.getTimeInMillis()-cal.getTimeInMillis());
		return cal.get(Calendar.YEAR)-1970;
	}

	public Osoba getOsoba(int index)
	{
		return osobe.get(index);
	}
	
	public void sortByColumn(int col) {
		switch (col) {
		case 0:
			Collections.sort(osobe, new Comparator<Osoba>() {
				@Override
				public int compare(Osoba o1, Osoba o2) {
					return o1.getJmbg().compareTo(o2.getJmbg());
				}
			});
			break;
		case 1:
			Collections.sort(osobe, new Comparator<Osoba>() {
				@Override
				public int compare(Osoba o1, Osoba o2) {
					return o1.getJmbg().compareTo(o2.getJmbg());
				}
			});
			break;
		case 2:
			Collections.sort(osobe, new Comparator<Osoba>() {
				@Override
				public int compare(Osoba o1, Osoba o2) {
					return o1.getIme().compareTo(o2.getIme());
				}
			});
			break;
		case 3:
			Collections.sort(osobe, new Comparator<Osoba>() {
				@Override
				public int compare(Osoba o1, Osoba o2) {
					return o1.getPrezime().compareTo(o2.getPrezime());
				}
			});
			break;
		case 4:
			Collections.sort(osobe, new Comparator<Osoba>() {
				@Override
				public int compare(Osoba o1, Osoba o2) {
					String s1 = o1.getPrebivaliste().getMjesto().getNaziv();
					String s2 = o2.getPrebivaliste().getMjesto().getNaziv();
					return s1.compareTo(s2);
				}
			});
			break;
		case 5:
			Collections.sort(osobe, new Comparator<Osoba>() {
				@Override
				public int compare(Osoba o1, Osoba o2) {
					return calcAgeByBirthDate(o1.getRodjen()) - calcAgeByBirthDate(o1.getRodjen());
				}
			});
			break;
		}
	}

}
